package com.easyExcel.handler;

import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;

import com.easyExcel.model.Model;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.poi.ss.util.CellRangeAddress;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

public class CashMergeStrategy implements SheetWriteHandler {

    private List<CellRangeAddress> mergeCellRanges;

    private final List<String> mergeColumnNames;

    private  final List<Model> data;

    private final List<String> unmergeList= Arrays.asList(new String[]{"line"});
    public boolean isunmergeColumn(String columnName)  {
        return unmergeList.contains(columnName);
    }

    public CashMergeStrategy(List<Model> data, List<String> mergeColumnNames) {
        this.mergeColumnNames=mergeColumnNames;
        this.data= data;
        List<Pair<Integer, Integer>> ranges = this.getRanges(data);
        ranges.removeIf(p -> Objects.equals(p.getLeft(), p.getRight()));
        // 算上title，row要+1
        this.mergeCellRanges = ranges.stream().map(p -> this.toRanges(p.getLeft(), p.getRight())).flatMap(List::stream).collect(Collectors.toList());
    }

    // todo 哪些列
    private List<CellRangeAddress> toRanges(int firstRow, int lastRow){
        List<CellRangeAddress> cellRanges = new ArrayList<>();
        //mergeColumnNames替换
        for (int i = 0; i < mergeColumnNames.size(); i++) {
            String columnName = mergeColumnNames.get(i);
            //去除非合并行
            if(isunmergeColumn(columnName)){
                continue;
            }

            for (int firstIndex = firstRow, lastIndex = firstRow; lastIndex <= lastRow; lastIndex++) {
                if (lastIndex == firstRow) {
                    continue;
                } else {
                    if (lastIndex == lastRow && data.get(firstIndex).isSameIndex(data.get(lastIndex),columnName)) {
                        cellRanges.add(new CellRangeAddress(firstIndex+1, lastIndex+1, i, i));
                    }
                    if (!data.get(firstIndex).isSameIndex(data.get(lastIndex),columnName)){
                        if(firstIndex+1!=lastIndex) {
                            cellRanges.add(new CellRangeAddress(firstIndex + 1, lastIndex, i, i));
                        }
                        firstIndex = lastIndex;
                    }
                }

            }
        }


        return cellRanges;
    }

    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        if(CollectionUtils.isNotEmpty(this.mergeCellRanges)){
            this.mergeCellRanges.forEach(cellRangeAddress -> writeSheetHolder.getSheet().addMergedRegionUnsafe(cellRangeAddress));
        }
    }


    private List<Pair<Integer, Integer>> getRanges(List<Model> list) {
        List<Pair<Integer, Integer>> ranges = new ArrayList<>();

        for (int left = 0, right = 0; right < list.size(); right++) {
            if (right == 0) {
                continue;
            }
            if (!list.get(left).isSameOrderItem(list.get(right))) {
                ranges.add(Pair.of(left, right - 1));
                left = right;

            }
            if (right == list.size() - 1) {
                ranges.add(Pair.of(left, right));
            }
        }

        return ranges;
    }
}
